package net

import (
	"github.com/gorilla/websocket"
	"log"
	"net/http"
)

// 处理 http 协议的服务

// 定义服务  服务地址 + 路由
type server struct {
	addr   string
	router *Router
}

func NewServer(addr string) *server {
	return &server{
		addr: addr,
	}
}

// Router 指定路由
func (s *server) Router(router *Router) {
	s.router = router
}

// Start 启动服务
func (s *server) Start() {
	// 映射
	http.HandleFunc("/", s.wsHandler)
	// 启动服务
	err := http.ListenAndServe(s.addr, nil)
	if err != nil {
		panic(err)
	}
}

// http 升级为 websocket 协议
var wsUpgrader = websocket.Upgrader{
	// 允许所以cors跨域请求
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

func (s *server) wsHandler(w http.ResponseWriter, r *http.Request) {
	// 思考 websocket
	// 1. http 升级为 websocket
	// 返回值 websocket协议链接 , err
	wsConn, err := wsUpgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Fatal("WebSocket 服务连接出错！ ", err)
	}
	log.Println("WebSocket 服务连接成功！")
	// websocket 通道建立之后 不管是客户端 还时服务端 都可以 收发消息
	// 发消息的时候 把消息当作路由 来去处理 消息是有格式的， 先定义消息格式
	// err = wsConn.WriteMessage(websocket.BinaryMessage, []byte("hello"))
	// fmt.Println(err)
	// 客户端发消息时 按规定格式发 {Name:"account.login"}  服务端收到之后进行解析 认为想想要处理登录逻辑
	wsSerer := NewWsServer(wsConn)
	// 设置路由
	wsSerer.Router(s.router)
	// 开启请求响应协程
	wsSerer.Start()
	// 握手 给前端 secret key
	wsSerer.Handshake()
}
